package com.yy.bugzillahelp.tool;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/*压缩文件夹*/
public class ZipTool {

    private String currentZipFilePath;
    private String sourceFilePath;
    private String pathHead;
    private ZipOutputStream zos;
    private FileInputStream fis;

    public ZipTool(String sourceFilePath, String currentZipFilePath) {
        try {
            this.sourceFilePath = sourceFilePath;
            this.currentZipFilePath = currentZipFilePath;
            pathHead = this.sourceFilePath.substring(0, this.sourceFilePath.lastIndexOf("/"));
            zos = new ZipOutputStream(new FileOutputStream(this.currentZipFilePath));
            //设定文件压缩级别
            zos.setLevel(9);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public ZipTool(String sourceFilePath, String currentZipFilePath, int flag) {
        try {
            this.sourceFilePath = sourceFilePath;
            this.currentZipFilePath = currentZipFilePath;
            pathHead = this.sourceFilePath.substring(0, this.sourceFilePath.lastIndexOf("\\"));
            zos = new ZipOutputStream(new FileOutputStream(this.currentZipFilePath));
            //设定文件压缩级别
            zos.setLevel(9);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 在当前条目中写入具体内容
    public void writeToEntryZip(String filePath) {
        try {
            fis = new FileInputStream(filePath);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
        byte[] buff = new byte[1024];
        int len = 0;
        try {
            while ((len = fis.read(buff)) != -1) {
                zos.write(buff, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 添加文件条目
    public void addFileEntryZip(String fileName) {
        try {
            zos.putNextEntry(new ZipEntry(fileName));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void addDirectoryEntryZip(String directoryName) {
        try {
            zos.putNextEntry(new ZipEntry(directoryName + "/"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 遍历文件夹
    public void listMyDirectory(String filePath) {
        File f = new File(filePath);
        File[] files = f.listFiles();
        if (files != null) {
            for (File currentFile : files) {
                // 设置条目名称(此步骤非常关键)
                String entryName = currentFile.getAbsolutePath().substring(pathHead.length() + 1);
                // 获取文件物理路径
                String absolutePath = currentFile.getAbsolutePath();
                if (currentFile.isDirectory()) {
                    addDirectoryEntryZip(entryName);
                    //进行递归调用
                    listMyDirectory(absolutePath);

                } else {
                    addFileEntryZip(entryName);
                    writeToEntryZip(absolutePath);
                }
            }
        }
    }

    // 主要流程
    public void mainWorkFlow() {
        listMyDirectory(this.sourceFilePath);
        if (zos != null) {
            try {
                zos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new ZipTool("F:/a/fountainDirectory", "F:/MyZip.zip").mainWorkFlow();
    }

    public static void unZip(String zipfile, String destDir) {
        unZip(zipfile, destDir, null);
    }

    public static void unZip(String zipfile, String destDir, String reName) {
//        destDir = destDir.endsWith("/") ? destDir : destDir + "/";
        byte b[] = new byte[1024];
        int length;
        ZipFile zipFile;
        try {
            zipFile = new ZipFile(new File(zipfile));
            Enumeration enumeration = zipFile.entries();
            ZipEntry zipEntry = null;
            while (enumeration.hasMoreElements()) {
                zipEntry = (ZipEntry) enumeration.nextElement();
                File loadFile;
                if (!"".equals(reName) || null != reName) {
                    loadFile = new File(destDir + reName);
                } else {
                    loadFile = new File(destDir + zipEntry.getName());
                }
                if (zipEntry.isDirectory()) {
                    loadFile.mkdirs();
                } else {
                    if (!loadFile.getParentFile().exists()) {
                        loadFile.getParentFile().mkdirs();
                    }
                    OutputStream outputStream = new FileOutputStream(loadFile);
                    InputStream inputStream = zipFile.getInputStream(zipEntry);
                    while ((length = inputStream.read(b)) > 0) {
                        outputStream.write(b, 0, length);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void getZip(List list, String path, String fileName) throws Exception {
        byte[] buffer = new byte[1024];

        String strZipName = fileName + ".zip";
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(path + strZipName));
        for (int j = 0; j < list.size(); j++) {
            String name = list.get(j).toString();
            FileInputStream fis = new FileInputStream(path + name);
            out.putNextEntry(new ZipEntry(name));
            int len;
            while ((len = fis.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            out.closeEntry();
            fis.close();
        }
        out.close();
    }
}
